package it.uniroma2.sd.db;

import java.util.Hashtable;
import java.util.Vector;

public class DB implements IDB
{
    /**
     * 
     */
    private static final long serialVersionUID = -8626255996116542577L;
    private Hashtable<String, Table> tables;
    private String id;

    /**
     * Get the DB's id
     * 
     * @return The specified id for the current DB
     */
    public String getId()
    {
	return id;
    }

    /**
     * Create a database with a specified identification name.
     * 
     * @param id The database identification name.
     */
    public DB(String id)
    {
	this.id = id;
	this.tables = new Hashtable<String, Table>();
    }

    @Override
    public boolean createTable(String tablename)
    {
	if (this.tables.containsKey(tablename))
	    return false;
	Table newtable = new Table(this, tablename);
	this.tables.put(newtable.getName(), newtable);
	return true;
    }

    // @Override
    // public ITable getTable(String tablename) // FIXME Sarebbe meglio evitare di fornire la table ed aggiungere tutti i metodi che l'utente può chiamare su di essa in questa classe, in modo che costituisca l'interfaccia di accesso a tutte le table
    // {
    // return this.tables.get(tablename);
    // }

    @Override
    public boolean deleteTable(String tablename)
    {
	return (this.tables.remove(tablename) != null);
    }

    @Override
    public boolean putInTable(String tablename, String rowkey, IColumn column)
    {
	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    table.put(rowkey, column);
	    return true;
	}
	else
	    return false;

    }

    @Override
    public boolean putInTable(String tablename, String rowkey, IColumn... columns)
    {
	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    for (IColumn c : columns)
	    {
		table.put(rowkey, c);
	    }
	    return true;
	}
	else
	    return false;
    }

    @Override
    public IColumn getColumnFromTable(String tablename, String rowkey, String columnkey)
    // FIXME ritorna null in 3 casi: NOtable, NOrow, NOcolumn. separare o usare exception
    {

	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    return table.getColumn(rowkey, columnkey);
	}
	else
	    return null;
    }

    @Override
    public Vector<IColumn> getAllColumnsFromTable(String tablename, String rowkey)
    // FIXME ritorna null in 2 casi: NOtable, NOrow. separare o usare exception
    {
	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    return table.getAllColumns(rowkey);
	}
	else
	    return null;
    }

    @Override
    public boolean deleteColumnFromTable(String tablename, String rowkey, String columnkey)
    // FIXME ritorna false in 3 casi: NOtable, NOrow, NOcolumn. separare o usare exception
    {
	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    return table.deleteColumn(rowkey, columnkey);
	}
	else
	    return false;
    }

    @Override
    public int deleteColumnsFromTable(String tablename, String rowkey, String... columnkey)
    {
	// TODO Auto-generated method stub
	// FIXME decidere se permettere la cancellazione di piu' colonne insieme.
	return 0;
    }

    @Override
    public boolean deleteRowFromTable(String tablename, String rowkey)
    // FIXME ritorna null in 2 casi: NOtable, NOrow. separare o usare exception
    {
	ITable table;
	if ((table = this.tables.get(tablename)) != null)
	{
	    return table.deleteRow(rowkey);
	}
	else
	    return false;
    }
}
